<?php

declare(strict_types=1);

namespace app\service\system;

use app\model\system\MenuApiModel;
use app\model\system\MenuModel;
use app\model\system\RoleMenuModel;
use owns\auth\UserAuth;
use think\facade\Db;

/**
 * 菜单栏
 */
class MenuService
{
    /**
     * 获取管理员菜单tree
     * @param integer $role_id 角色id
     */
    public function userMenu(int $role_id): array
    {
        $menuList = MenuModel::field('o_system_menu.*')
            ->join('o_system_role_menu', 'o_system_role_menu.menu_id=o_system_menu.id')
            ->where('o_system_role_menu.role_id', $role_id)
            ->whereIn('o_system_menu.type', ['menu'])
            ->order('sort asc, id desc')
            ->select();
        $tree = [];
        foreach ($menuList as $item) {
            $tree[] = [
                'id' => $item->id,
                'parent_id' => $item->parent_id,
                'name' => $item->name,
                'path' => $item->path,
                'component' => $item->component,
                'redirect' => $item->redirect,
                'meta' => [
                    'title' => $item->title,
                    'hidden' => $item->hidden ? true : false,
                    'affix' => $item->affix ? true : false,
                    'icon' => $item->icon,
                    'type' => $item->type,
                    'hiddenBreadcrumb' => $item->hidden_breadcrumb ? true : false,
                    'active' => $item->active,
                    'color' => $item->color,
                    'fullpage' => false,
                ]
            ];
        }
        return recursion($tree, 0, false, 'parent_id');
    }
    /**
     * 获取角色菜单接口
     * @param integer $role_id 角色id
     * @param string $type code只获取接口标识
     */
    public function roleMenuApi(int $role_id, $type = ''): array
    {
        $apilist = RoleMenuModel::alias('rm')
            ->field('ma.code,ma.url,ma.api_method')
            ->join('o_system_menu_api ma', 'ma.menu_id=rm.menu_id')
            ->where('rm.role_id', $role_id)
            ->select();
        // 接口标识
        if ($type == 'code') {
            $result = [];
            foreach ($apilist as $item) {
                if ($item->code) {
                    $result[] = $item->code;
                }
            }
            return $result;
        }
        return $apilist->toArray();
    }
    /**
     * 列表tree
     * @param array $param
     */
    public function list(array $param): array
    {
        $list = MenuModel::custom($param)
            ->with(['apiList'])
            ->order('sort asc, id desc')
            ->select();
        $tree = [];
        foreach ($list as $item) {
            $tree[] = [
                'id' => $item->id,
                'parent_id' => $item->parent_id,
                'name' => $item->name,
                'path' => $item->path,
                'component' => $item->component,
                'redirect' => $item->redirect,
                'apiList' => $item->apiList,
                'sort' => $item->sort,
                'meta' => [
                    'title' => $item->title,
                    'hidden' => $item->hidden ? true : false,
                    'affix' => $item->affix ? true : false,
                    'icon' => $item->icon,
                    'type' => $item->type,
                    'hidden_breadcrumb' => $item->hidden_breadcrumb,
                    'active' => $item->active,
                    'color' => $item->color,
                    'fullpage' => false,
                ]
            ];
        }
        return recursion($tree, 0, false, 'parent_id');
    }
    /**
     * 菜单编辑
     * @param array $data
     * @param integer $id
     */
    public function edit(array $data, int $id): int
    {
        $auth = UserAuth::instance();
        $menu = MenuModel::find($id);
        if ($menu) {
            $menu->updated_by = $auth->username();
        } else {
            $menu = new MenuModel();
            $menu->parent_id = $data['parent_id'] ?? 0;
            $menu->created_by = $auth->username();
        }
        $menu->title = trim($data['meta']['title']);
        $menu->name = trim($data['name']);
        $menu->type = $data['meta']['type'];
        $menu->sort = $data['sort'];
        if ($menu->type == 'button') {
            $menu->icon = '';
            $menu->component = '';
            $menu->path = '';
            $menu->redirect = '';
            $menu->hidden = 0;
            $menu->color = '';
            $menu->active = '';
            $menu->hidden_breadcrumb = 0;
            $menu->affix = 0;
            $menu->fullpage = 0;
        } else {
            $menu->component = trim($data['component']);
            $menu->path = trim($data['path']);
            $menu->redirect = trim($data['redirect']);
            $menu->icon = $data['meta']['icon'];
            $menu->hidden = $data['meta']['hidden'] ? 1 : 0;
            $menu->color = $data['meta']['color'];
            $menu->active = $data['meta']['active'];
            $menu->hidden_breadcrumb = $data['meta']['hidden_breadcrumb'] ? 1 : 0;
            $menu->affix = $data['meta']['affix'] ? 1 : 0;
            $menu->fullpage = $data['meta']['fullpage'] ? 1 : 0;
        }
        if (!$menu->save()) {
            tips('保存失败');
        }
        // 菜单接口
        MenuApiModel::where('menu_id', $menu->id)->delete();
        $apiList = [];
        foreach ($data['apiList'] as $api) {
            $apiList[] = [
                'menu_id' => $menu->id,
                'code' => trim($api['code']),
                'url' => trim($api['url']),
                'api_method' => $api['api_method'],
                'is_record' => $api['is_record']
            ];
        }
        if ($apiList) {
            Db::name('system_menu_api')->insertAll($apiList);
        }
        return (int)$menu->id;
    }
    /**
     * 删除菜单
     * @param array $ids
     */
    public function delete(array $ids): void
    {
        if (!$ids) {
            tips('无菜单信息');
        }
        foreach ($ids as $id) {
            MenuModel::destroy($id);
            $this->_deleteChildren((int) $id);
        }
    }
    /**
     * 删除下级菜单
     * @param integer $parent_id
     */
    protected function _deleteChildren(int $parent_id): void
    {
        $children = MenuModel::where('parent_id', $parent_id)->select();
        foreach ($children as $menu) {
            MenuModel::destroy($menu->id);
            $this->_deleteChildren($menu->id);
        }
    }
}
